package com.htfyun.ft.common;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;

import com.htfyun.ft.utils.DebugLog;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class SDCardInfo extends BroadcastReceiver{

    private final Context mContext;

    private volatile boolean isRegistered = false;

    private OnSDCardStatChangedListener onSDCardStatChangedListener;
    private OnVolumeStateChangedListener onVolumeStateChangedListener;

    public SDCardInfo(Context ctx) {
        mContext = ctx;
    }
    public synchronized void startMonitor(OnSDCardStatChangedListener listener) {
        if (isRegistered) {
            return;
        }
        isRegistered = true;

        onSDCardStatChangedListener = listener;
        mContext.registerReceiver(this, getIntentFilterOfSDCard());
    }

    public synchronized void startMonitor() {
        if (isRegistered) {
            return;
        }
        isRegistered = true;

        mContext.registerReceiver(this, getIntentFilterOfSDCard());
    }

    public void stopMonitor() {
        if (!isRegistered) {
            return;
        }
        isRegistered = false;

        onSDCardStatChangedListener = null;
        onVolumeStateChangedListener = null;
        mContext.unregisterReceiver(this);
    }

    public void setOnSDCardStatChangedListener(OnSDCardStatChangedListener onSDCardStatChangedListener) {
        this.onSDCardStatChangedListener = onSDCardStatChangedListener;
    }

    public void setOnVolumeStateChangedListener(OnVolumeStateChangedListener onVolumeStateChangedListener) {
        this.onVolumeStateChangedListener = onVolumeStateChangedListener;
    }

    public String getVolumePath(StorageVolume volume) {
        try {
            if (volume.getState().equals(Environment.MEDIA_MOUNTED)) {
                    Method getPath = StorageVolume.class.getMethod("getPath");
                    String path = (String) getPath.invoke(volume);
                    DebugLog.e("Storage Path--->" + path);

                    return path;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    public String getVolumeId(StorageVolume volume) {

        try {

            Method getId = StorageVolume.class.getMethod("getId");
            String id = (String) getId.invoke(volume);
            DebugLog.e("Storage getId--->" + id);

            return id;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    public List<StorageVolume> getPublicVolumesExceptSD() {
        List<StorageVolume> volList = new ArrayList<>();
        StorageManager sm = mContext.getSystemService(StorageManager.class);

        if (sm == null) {
            return volList;
        }

        List<StorageVolume> volumes = sm.getStorageVolumes();

        for (StorageVolume vol : volumes) {
            if (!vol.isPrimary() && !vol.getDescription(mContext).contains("SD")) {
                volList.add(vol);
            }
        }
        return volList;
    }

    public boolean isSDCardMounted() {

        StorageManager sm = mContext.getSystemService(StorageManager.class);

        if (sm == null) {
            return false;
        }

        List<StorageVolume> volList = sm.getStorageVolumes();
        if (volList == null) {
            return false;
        }

        for (StorageVolume vol : volList) {
            DebugLog.e("vol state = " + vol.getState() + ", desc = " + vol.getDescription(mContext) + ", isPrimary = " + vol.isPrimary());
        }

        for (StorageVolume vol : volList) {
            if (vol.getState().equals(Environment.MEDIA_MOUNTED)
                    && vol.getDescription(mContext).contains("SD")) {

                return true;
            }
        }

        return false;

    }

    private String getSDCardPath() {

        if (!isSDCardMounted()) {
            return "";
        }

        StorageManager sm = mContext.getSystemService(StorageManager.class);

        if (sm == null) {
            return "";
        }

        List<StorageVolume> volList = sm.getStorageVolumes();
        if (volList == null) {
            return "";
        }

        for (StorageVolume vol : volList) {
            if (vol.getState().equals(Environment.MEDIA_MOUNTED)
                    && vol.getDescription(mContext).contains("SD")) {

                return getVolumePath(vol);
            }
        }

        return "";

    }


    private void updateWhenSDCardStatChanged() {

        final String path = getSDCardPath();

        if (onSDCardStatChangedListener != null) {
            onSDCardStatChangedListener.onSDCardStatChangedListener(this,
                    !TextUtils.isEmpty(path) ? new StatFs(path) : null);
        }
    }

    private IntentFilter getIntentFilterOfSDCard() {
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);

        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);

        intentFilter.addAction(Intent.ACTION_MEDIA_REMOVED);
        intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);

        intentFilter.addDataScheme("file");

        return intentFilter;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        DebugLog.e("action =  " + action);

        if (action == null) {
            return;
        }
        updateWhenSDCardStatChanged();

        if (onVolumeStateChangedListener != null) {
            onVolumeStateChangedListener.onVolumeStateChangedListener(this, action, intent.getData());
        }
    }

    public interface OnSDCardStatChangedListener {
        void onSDCardStatChangedListener(@NonNull SDCardInfo info, @Nullable StatFs statFs);
    }

    public interface OnVolumeStateChangedListener {
        void onVolumeStateChangedListener(SDCardInfo sdCardInfo, String action, Uri data);
    }

}
